package com.robot.base.view

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.TypedArray
import android.graphics.*
import android.graphics.Shader.TileMode
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build.VERSION
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewOutlineProvider
import android.widget.ImageView
import android.widget.ImageView.ScaleType
import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.annotation.RequiresApi
import com.robot.base.R
import java.lang.Exception

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

class CircleImageView : androidx.appcompat.widget.AppCompatImageView {
    private val mDrawableRect: RectF
    private val mBorderRect: RectF
    private val mShaderMatrix: Matrix
    private val mBitmapPaint: Paint?
    private val mBorderPaint: Paint
    private val mCircleBackgroundPaint: Paint
    private var mBorderColor: Int
    private var mBorderWidth: Int
    private var mCircleBackgroundColor: Int
    private var mBitmap: Bitmap? = null
    private var mBitmapShader: BitmapShader? = null
    private var mBitmapWidth = 0
    private var mBitmapHeight = 0
    private var mDrawableRadius = 0f
    private var mBorderRadius = 0f
    private var mColorFilter: ColorFilter? = null
    private var mReady = false
    private var mSetupPending = false
    private var mBorderOverlay = false
    private var mDisableCircularTransformation = false

    constructor(context: Context?) : super(context!!) {
        mDrawableRect = RectF()
        mBorderRect = RectF()
        mShaderMatrix = Matrix()
        mBitmapPaint = Paint()
        mBorderPaint = Paint()
        mCircleBackgroundPaint = Paint()
        mBorderColor = -16777216
        mBorderWidth = 0
        mCircleBackgroundColor = 0
        init()
    }

    @JvmOverloads
    constructor(context: Context, attrs: AttributeSet?, defStyle: Int = 0) : super(
        context,
        attrs,
        defStyle
    ) {
        mDrawableRect = RectF()
        mBorderRect = RectF()
        mShaderMatrix = Matrix()
        mBitmapPaint = Paint()
        mBorderPaint = Paint()
        mCircleBackgroundPaint = Paint()
        mBorderColor = -16777216
        mBorderWidth = 0
        mCircleBackgroundColor = 0
        val a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0)
        mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, 0)
        mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, -16777216)
        mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, false)
        mCircleBackgroundColor =
            a.getColor(R.styleable.CircleImageView_civ_circle_background_color, 0)
        a.recycle()
        init()
    }

    private fun init() {
        super.setScaleType(CircleImageView.Companion.SCALE_TYPE)
        mReady = true
        if (VERSION.SDK_INT >= 21) {
            this.outlineProvider = OutlineProvider()
        }
        if (mSetupPending) {
            setup()
            mSetupPending = false
        }
    }

    override fun getScaleType(): ScaleType? {
        return SCALE_TYPE
    }

    override fun setScaleType(scaleType: ScaleType) {
        require(scaleType == CircleImageView.Companion.SCALE_TYPE) {
            String.format(
                "ScaleType %s not supported.",
                scaleType
            )
        }
    }

    override fun setAdjustViewBounds(adjustViewBounds: Boolean) {
        require(!adjustViewBounds) { "adjustViewBounds not supported." }
    }

    override fun onDraw(canvas: Canvas) {
        if (mDisableCircularTransformation) {
            super.onDraw(canvas)
        } else if (mBitmap != null) {
            if (mCircleBackgroundColor != 0) {
                canvas.drawCircle(
                    mDrawableRect.centerX(), mDrawableRect.centerY(),
                    mDrawableRadius, mCircleBackgroundPaint
                )
            }
            canvas.drawCircle(
                mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius,
                mBitmapPaint!!
            )
            if (mBorderWidth > 0) {
                canvas.drawCircle(
                    mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius,
                    mBorderPaint
                )
            }
        }
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        setup()
    }

    override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
        super.setPadding(left, top, right, bottom)
        setup()
    }

    override fun setPaddingRelative(start: Int, top: Int, end: Int, bottom: Int) {
        super.setPaddingRelative(start, top, end, bottom)
        setup()
    }

    var borderColor: Int
        get() = mBorderColor
        set(borderColor) {
            if (borderColor != mBorderColor) {
                mBorderColor = borderColor
                mBorderPaint.color = mBorderColor
                this.invalidate()
            }
        }
    var circleBackgroundColor: Int
        get() = mCircleBackgroundColor
        set(circleBackgroundColor) {
            if (circleBackgroundColor != mCircleBackgroundColor) {
                mCircleBackgroundColor = circleBackgroundColor
                mCircleBackgroundPaint.color = circleBackgroundColor
                this.invalidate()
            }
        }

    fun setCircleBackgroundColorResource(@ColorRes circleBackgroundRes: Int) {
        circleBackgroundColor =
            this.context.resources.getColor(circleBackgroundRes)
    }

    var borderWidth: Int
        get() = mBorderWidth
        set(borderWidth) {
            if (borderWidth != mBorderWidth) {
                mBorderWidth = borderWidth
                setup()
            }
        }
    var isBorderOverlay: Boolean
        get() = mBorderOverlay
        set(borderOverlay) {
            if (borderOverlay != mBorderOverlay) {
                mBorderOverlay = borderOverlay
                setup()
            }
        }
    var isDisableCircularTransformation: Boolean
        get() = mDisableCircularTransformation
        set(disableCircularTransformation) {
            if (mDisableCircularTransformation != disableCircularTransformation) {
                mDisableCircularTransformation = disableCircularTransformation
                initializeBitmap()
            }
        }

    override fun setImageBitmap(bm: Bitmap) {
        super.setImageBitmap(bm)
        initializeBitmap()
    }

    override fun setImageDrawable(drawable: Drawable?) {
        super.setImageDrawable(drawable)
        initializeBitmap()
    }

    override fun setImageResource(@DrawableRes resId: Int) {
        super.setImageResource(resId)
        initializeBitmap()
    }

    override fun setImageURI(uri: Uri?) {
        super.setImageURI(uri)
        initializeBitmap()
    }

    override fun setColorFilter(cf: ColorFilter) {
        if (cf !== mColorFilter) {
            mColorFilter = cf
            applyColorFilter()
            this.invalidate()
        }
    }

    override fun getColorFilter(): ColorFilter {
        return mColorFilter!!
    }

    private fun applyColorFilter() {
        if (mBitmapPaint != null) {
            mBitmapPaint.colorFilter = mColorFilter
        }
    }

    private fun getBitmapFromDrawable(drawable: Drawable?): Bitmap? {
        return if (drawable == null) {
            null
        } else if (drawable is BitmapDrawable) {
            drawable.bitmap
        } else {
            try {
                val bitmap: Bitmap = if (drawable is ColorDrawable) {
                    Bitmap.createBitmap(
                        2,
                        2,
                        BITMAP_CONFIG!!
                    )
                } else {
                    Bitmap.createBitmap(
                        drawable.intrinsicWidth,
                        drawable.intrinsicHeight,
                        BITMAP_CONFIG!!
                    )
                }
                val canvas = Canvas(bitmap)
                drawable.setBounds(0, 0, canvas.width, canvas.height)
                drawable.draw(canvas)
                bitmap
            } catch (var4: Exception) {
                var4.printStackTrace()
                null
            }
        }
    }

    private fun initializeBitmap() {
        if (mDisableCircularTransformation) {
            mBitmap = null
        } else {
            mBitmap = getBitmapFromDrawable(this.drawable)
        }
        setup()
    }

    private fun setup() {
        if (!mReady) {
            mSetupPending = true
        } else if (this.width != 0 || this.height != 0) {
            if (mBitmap == null) {
                this.invalidate()
            } else {
                mBitmapShader = BitmapShader(mBitmap!!, TileMode.CLAMP, TileMode.CLAMP)
                mBitmapPaint!!.isAntiAlias = true
                mBitmapPaint.isDither = true
                mBitmapPaint.isFilterBitmap = true
                mBitmapPaint.shader = mBitmapShader
                mBorderPaint.style = Paint.Style.STROKE
                mBorderPaint.isAntiAlias = true
                mBorderPaint.color = mBorderColor
                mBorderPaint.strokeWidth = mBorderWidth.toFloat()
                mCircleBackgroundPaint.style = Paint.Style.FILL
                mCircleBackgroundPaint.isAntiAlias = true
                mCircleBackgroundPaint.color = mCircleBackgroundColor
                mBitmapHeight = mBitmap!!.height
                mBitmapWidth = mBitmap!!.width
                mBorderRect.set(calculateBounds())
                mBorderRadius = Math.min(
                    (mBorderRect.height() - mBorderWidth.toFloat()) / 2.0f,
                    (mBorderRect.width() - mBorderWidth.toFloat()) / 2.0f
                )
                mDrawableRect.set(mBorderRect)
                if (!mBorderOverlay && mBorderWidth > 0) {
                    mDrawableRect.inset(
                        mBorderWidth.toFloat() - 1.0f,
                        mBorderWidth.toFloat() - 1.0f
                    )
                }
                mDrawableRadius =
                    Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f)
                applyColorFilter()
                updateShaderMatrix()
                this.invalidate()
            }
        }
    }

    private fun calculateBounds(): RectF {
        val availableWidth = this.width - this.paddingLeft - this.paddingRight
        val availableHeight = this.height - this.paddingTop - this.paddingBottom
        val sideLength = Math.min(availableWidth, availableHeight)
        val left = this.paddingLeft.toFloat() + (availableWidth - sideLength).toFloat() / 2.0f
        val top = this.paddingTop.toFloat() + (availableHeight - sideLength).toFloat() / 2.0f
        return RectF(left, top, left + sideLength.toFloat(), top + sideLength.toFloat())
    }

    private fun updateShaderMatrix() {
        var dx = 0.0f
        var dy = 0.0f
        mShaderMatrix.set(null as Matrix?)
        val scale: Float
        if (mBitmapWidth.toFloat() * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight.toFloat()) {
            scale = mDrawableRect.height() / mBitmapHeight.toFloat()
            dx = (mDrawableRect.width() - mBitmapWidth.toFloat() * scale) * 0.5f
        } else {
            scale = mDrawableRect.width() / mBitmapWidth.toFloat()
            dy = (mDrawableRect.height() - mBitmapHeight.toFloat() * scale) * 0.5f
        }
        mShaderMatrix.setScale(scale, scale)
        mShaderMatrix.postTranslate(
            (dx + 0.5f).toInt().toFloat() + mDrawableRect.left, (dy + 0.5f).toInt()
                .toFloat() + mDrawableRect.top
        )
        mBitmapShader!!.setLocalMatrix(mShaderMatrix)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent): Boolean {
        return if (mDisableCircularTransformation) {
            super.onTouchEvent(event)
        } else {
            inTouchableArea(event.x, event.y) && super.onTouchEvent(event)
        }
    }

    private fun inTouchableArea(x: Float, y: Float): Boolean {
        return if (mBorderRect.isEmpty) {
            true
        } else {
            Math.pow((x - mBorderRect.centerX()).toDouble(), 2.0) + Math.pow(
                (y - mBorderRect.centerY()).toDouble(), 2.0
            ) <= Math.pow(mBorderRadius.toDouble(), 2.0)
        }
    }

    companion object {
        private var SCALE_TYPE: ScaleType? = null
        private var BITMAP_CONFIG: Bitmap.Config? = null
        private const val COLORDRAWABLE_DIMENSION = 2
        private const val DEFAULT_BORDER_WIDTH = 0
        private const val DEFAULT_BORDER_COLOR = -16777216
        private const val DEFAULT_CIRCLE_BACKGROUND_COLOR = 0
        private const val DEFAULT_BORDER_OVERLAY = false

        init {
            SCALE_TYPE =
                ScaleType.CENTER_CROP
            BITMAP_CONFIG =
                Bitmap.Config.ARGB_8888
        }
    }

    @RequiresApi(api = 21)
    private inner class OutlineProvider() : ViewOutlineProvider() {
        override fun getOutline(view: View, outline: Outline) {
            if (mDisableCircularTransformation) {
                BACKGROUND.getOutline(view, outline)
            } else {
                val bounds = Rect()
                mBorderRect.roundOut(bounds)
                outline.setRoundRect(bounds, bounds.width().toFloat() / 2.0f)
            }
        }
    }
}